#coding:utf-8

import os
import sys
import types
import time
import utils
import case
import error
import data

class TestResult(object):
    _TESTCASE_FLAG = '_data_case'
    def __init__(self, fpath, overwrite=False):
        self.engine = data.get_engine(fpath, overwrite)
        self.session = data.Session(bind=self.engine)
        
    def start_test(self, test):
        case = data.TestCase(test.name, test.path, test.description)
        self.session.add(case)
        setattr(test, self._TESTCASE_FLAG, case)
    
    def stop_test(self, test):
        if hasattr(test, self._TESTCASE_FLAG):
            delattr(test, self._TESTCASE_FLAG)
        self.session.commit()
        
    def add_test_result(self, test, args, error_list, time_start, time_stop):
        testcase = getattr(test, self._TESTCASE_FLAG, None)
        if testcase is not None:
            result = data.Result(False if error_list else True, time_start, time_stop, args)
            testcase.results.append(result)
            for order in range(len(error_list)):
                exctype, value, tb = error_list[order]
                messages = error.format_exception(exctype, value, tb)
                for msg, env in messages:
                    result.messages.append(data.Message(order, msg, env))
        else:
            raise Exception, "db not found?"
        self.session.commit()


class TestRunner(object):
    """ 1, run
        2, collect data
        3, record test
    """
    def run(self, test_suite, result):
        for tc in test_suite:
            try:
                tc.run(result)
            except:
                result.session.add(data.SystemError())
                result.session.commit()
        return result
            
    

class HtmlTestRunner(TestRunner):
    def __init__(self, datapath, reportpath):
        self.datapath = datapath
        self.reportpath = reportpath

    def run(self, test_suite, result):
        time_start = time.strftime("%Y-%m-%d %H:%M:%S")
        result = TestRunner.run(self, test_suite, result)
        time_stop = time.strftime("%Y-%m-%d %H:%M:%S")
        utils.make_html_report(self.datapath, self.reportpath, 
                               session=result.session, time_start=time_start, time_stop=time_stop)
        return result
    
    def load_and_run(self, test_dir_path, suite_list):
        """ just for conveniency """
        suite = case.TestSuite()
        suite.make_suite(test_dir_path, suite_list)
        return self.run(suite, TestResult(self.datapath))
